package com.rf.richfitwheel.dyn.business.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.rf.richfitwheel.common.contants.Constant;
import com.rf.richfitwheel.dyn.business.entity.SysBusinessDesigner;
import com.rf.richfitwheel.dyn.business.entity.SysBusinessDesignerComponent;
import com.rf.richfitwheel.dyn.business.entity.SysFormDesigner;
import com.rf.richfitwheel.dyn.business.mapper.SysBusinessDesignerMapper;
import com.rf.richfitwheel.dyn.business.mapper.SysFormDesignerMapper;
import com.rf.richfitwheel.dyn.business.service.SysBusinessDesignerComponentService;
import com.rf.richfitwheel.dyn.business.service.SysBusinessDesignerService;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 应用设计记录 服务层实现。
 *
 * @author richfitwheel
 * @since 2025-02-18
 */
@Service
public class SysBusinessDesignerServiceImpl extends ServiceImpl<SysBusinessDesignerMapper, SysBusinessDesigner>  implements SysBusinessDesignerService{

    @Resource
    private SysBusinessDesignerComponentService sysBusinessDesignerComponentService;
    @Resource
    private SysFormDesignerMapper sysFormDesignerMapper;
    @Resource
    private ObjectMapper serializingObjectMapper;

    /**
     * 根据id获取表单信息（包含表单下的组件信息）
     *
     * @param designerId 表单id
     * @return 表单信息
     */
    @Override
    public SysBusinessDesigner getSysBusinessDesignerHasDetail(String designerId) {
        SysBusinessDesigner designer = this.getById(designerId);
        Assert.notNull(designer, "查询的信息不存在");
        List<SysBusinessDesignerComponent> componentList = sysBusinessDesignerComponentService.queryByDesignerId(designerId);
        designer.setComponentList(componentList);
        return designer;
    }

    /**
     * 根据表单设计ID获取主表表结构与前端元素之间的对应关系
     *
     * @param designerId 表单设计ID
     * @return 对应关系
     */
    @Override
    @Cacheable(value="skivingTableMapping",key="#p0 + '_designerId'")
    public Map<String, Map<String, String>> getMainTableMappingByDesignerId(String designerId) throws JsonProcessingException {
        //获取设计信息
        SysBusinessDesigner businessDesigner = this.getSysBusinessDesignerHasDetail(designerId);
        //组件设计信息
        List<SysFormDesigner> forms = sysFormDesignerMapper.selectListByQuery(
                QueryWrapper.create().where(SysFormDesigner::getId).in(
                        businessDesigner.getComponentList().stream().map(SysBusinessDesignerComponent::getComponentId)
                                .collect(Collectors.toList())
                ));
        Map<String, Map<String, String>> mapping = new HashMap<>();
        Map<String, String> mainMapping = new HashMap<>();
        for (SysFormDesigner form : forms) {
            JsonNode columns = serializingObjectMapper.readTree(form.getFormColumnJson());
            columns.get("main").forEach(col -> {
                mainMapping.put(col.get("widgetName").asText(), col.get("columnName").asText());
            });
            if (columns.get("sub") != null && Objects.nonNull(columns.get("sub"))) {
                //子表
                columns.get("sub").fields().forEachRemaining(sub -> {
                    Map<String, String> subMapping = new HashMap<>();
                    sub.getValue().forEach(col -> {
                        subMapping.put(col.get("widgetName").asText(), col.get("columnName").asText());
                    });
                    mapping.put(sub.getKey(), subMapping);
                });
            }
        }
        mapping.put("main", mainMapping);
        return mapping;
    }

    /**
     * 根据编码获取最新版本已发布的信息
     *
     * @param code 表单设计编码
     * @return 表单设计详情
     */
    @Override
    public SysBusinessDesigner getLatestInfoByCode(String code) {
        QueryWrapper queryWrapper = QueryWrapper.create().from(SysBusinessDesigner.class).as("oo")
                .join(
                        QueryWrapper.create().select(
                                        QueryMethods.column(SysBusinessDesigner::getDesignerCode),
                                        QueryMethods.max(QueryMethods.column(SysBusinessDesigner::getVersion)).as("version"))
                                .from(SysBusinessDesigner.class)
                                .where(SysBusinessDesigner::getResStatus).eq(Constant.COMMON_YES_OR_NO_YES)
                                .groupBy(SysBusinessDesigner::getDesignerCode)).as("ii")
                .on(
                        wrapper -> wrapper.where("oo.designer_code = ii.designer_code")
                                .and("oo.version = ii.version")
                ).where(SysBusinessDesigner::getDesignerCode).eq(code);
        SysBusinessDesigner designer = this.getOne(queryWrapper);
        Assert.notNull(designer, "查询的信息不存在");
        List<SysBusinessDesignerComponent> componentList = sysBusinessDesignerComponentService.queryByDesignerId(designer.getId());
        designer.setComponentList(componentList);
        return designer;
    }
}
